package com.flot.yazb.aop;

import android.os.SystemClock;
import android.util.Log;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class DebouncingClickProxy {

    private static final String TAG = "DebouncingClickProxy";

    private static InvokeUtil sOnClickMethod = new InvokeUtil(),
            sDoClickMethod = new InvokeUtil();

    @Around("execution(* android.view.View.OnClickListener.onClick(..))")
    public void onClickAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        String key = proceedingJoinPoint.getArgs()[0].toString()+proceedingJoinPoint.getSignature().toString();
        if(sOnClickMethod.isValid(key)) {
            proceedingJoinPoint.proceed();
            Log.d(TAG, "View.onClick valid: " + key);
        }

        Log.d(TAG, "View.onClick out: " + key);
    }

    @Around("execution(* butterknife.internal.DebouncingOnClickListener.doClick(..))")
    public void onClickButterKnifeAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        String key = proceedingJoinPoint.getArgs()[0].toString()+proceedingJoinPoint.getSignature().toString();
        Log.d(TAG, "ButterKnife.doClick in: " + key);
        if(sDoClickMethod.isValid(key)) {
            proceedingJoinPoint.proceed();
            Log.d(TAG, "ButterKnife.doClick valid: " + key);
        }

        Log.d(TAG, "ButterKnife.doClick out: " + key);
    }

    static class InvokeUtil {

        public static final int MIN_INVOKE_DELAY_TIME = 500;

        public long lastInvokeTime = -9999L;
        public String mKey="";
        public boolean isValid(String key){
            long currentTime = SystemClock.elapsedRealtime();
            if(!mKey.equals(key)){
                lastInvokeTime = currentTime;
                mKey=key;
                return true;
            }else if(currentTime - lastInvokeTime > MIN_INVOKE_DELAY_TIME){
                lastInvokeTime = currentTime;
                mKey=key;
                return true;
            }
            return false;
        }
    }
}
